package utils

import (
	"context"
	"fmt"
	"time"

	"github.com/redis/go-redis/v9"
)

var RedisClient *redis.Client

// InitRedis 初始化Redis客户端
func InitRedis() error {
	if AppConfig == nil {
		return fmt.Errorf("配置未初始化")
	}

	RedisClient = redis.NewClient(&redis.Options{
		Addr:            fmt.Sprintf("%s:%d", AppConfig.RedisHost, AppConfig.RedisPort),
		Password:        AppConfig.RedisPswd,
		DB:              AppConfig.RedisDB,
		PoolSize:        20,               // 连接池大小
		MinIdleConns:    5,                // 最少空闲连接数
		MaxIdleConns:    10,               // 最多空闲连接数
		ConnMaxLifetime: time.Hour,        // 连接最大生存时间
		ConnMaxIdleTime: 30 * time.Minute, // 连接最大空闲时间
		DialTimeout:     5 * time.Second,  // 连接超时
		ReadTimeout:     3 * time.Second,  // 读取超时
		WriteTimeout:    3 * time.Second,  // 写入超时
	})

	// 测试连接
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := RedisClient.Ping(ctx).Err(); err != nil {
		return fmt.Errorf("Redis连接失败: %v", err)
	}

	Info("Redis连接成功", map[string]interface{}{
		"host": AppConfig.RedisHost,
		"port": AppConfig.RedisPort,
		"db":   AppConfig.RedisDB,
	})

	return nil
}

// 缓存相关常量
const (
	CacheKeyUser     = "user:%s"     // 用户信息
	CacheKeyDepart   = "depart:%d"   // 部门信息
	CacheKeyTemplate = "template:%d" // 模板信息
	CacheKeyGoods    = "goods:%d"    // 商品信息

	// 缓存过期时间
	CacheExpireUser     = 30 * time.Minute // 用户信息缓存时间
	CacheExpireDepart   = 60 * time.Minute // 部门信息缓存时间
	CacheExpireTemplate = 60 * time.Minute // 模板信息缓存时间
	CacheExpireGoods    = 15 * time.Minute // 商品信息缓存时间
)

// GetFromCache 从缓存获取数据
func GetFromCache(ctx context.Context, key string) ([]byte, error) {
	return RedisClient.Get(ctx, key).Bytes()
}

// SetToCache 设置缓存数据
func SetToCache(ctx context.Context, key string, value interface{}, expiration time.Duration) error {
	return RedisClient.Set(ctx, key, value, expiration).Err()
}

// DeleteFromCache 从缓存删除数据
func DeleteFromCache(ctx context.Context, key string) error {
	return RedisClient.Del(ctx, key).Err()
}

// ExistsInCache 检查缓存中是否存在数据
func ExistsInCache(ctx context.Context, key string) bool {
	result := RedisClient.Exists(ctx, key)
	return result.Val() > 0
}

// GetCacheKeys 获取缓存键列表
func GetCacheKeys(ctx context.Context, pattern string) ([]string, error) {
	return RedisClient.Keys(ctx, pattern).Result()
}

// ClearCacheByPattern 按模式清理缓存
func ClearCacheByPattern(ctx context.Context, pattern string) error {
	keys, err := GetCacheKeys(ctx, pattern)
	if err != nil {
		return err
	}

	if len(keys) > 0 {
		return RedisClient.Del(ctx, keys...).Err()
	}

	return nil
}
